#pragma once
#include "stdafx.h"
#include "StreamPage.h"
#include "Types.h"
#include "BufferConstraint.h"
#include <boost/shared_ptr.hpp>
#include "Element.h"
#include "AbstractBuffer.h"
#include <boost/unordered_map.hpp>

/* a buffer to saves the relation information 
insert element in, and delete element by id
*/
class ElementIterator;
class SetElementIterator;
class RelationBuffer:public AbstractBuffer
{
private:

	boost::unordered_map<DocumentId, MemoryPosition>idPositionMap;
	MemoryPosition freePositionHead;

public:
	RelationBuffer(void)
	{

		this->freePositionHead.pageIndex=0;
		this->freePositionHead.chunkIndex=0;

	}
	~RelationBuffer(void){}
	inline void insertElement(Element& element)
	{

		bool bl = isFull();
		assert(bl==false);
		if(bl==true)
		{
			std::cout<<"memory not enough"<<std::endl;
			bool bl = isFull();
			exit(1);
		}
		MemoryPosition elementPosition = this->freePositionHead;

		this->setElementByMemoryPosition(element,elementPosition);
		this->idPositionMap.insert(make_pair(element.id,elementPosition));
		this->getNextPosition(elementPosition,freePositionHead);

	}
	inline void deleteElement(Element& element)
	{
		DocumentId id = element.id;
		boost::unordered_map<DocumentId, MemoryPosition>::iterator it;
		it = this->idPositionMap.find(id);
		assert(it!=this->idPositionMap.end());
		MemoryPosition elementPosition = it->second;
		this->setNextPosition(elementPosition,freePositionHead);
		this->freePositionHead = elementPosition;
		this->idPositionMap.erase(it);
	}
	inline bool isFull(void)
	{
		bool ret;
		if(!isValidMemoryPosition(freePositionHead))
		{
			ret = this->allocateNewPage();
			if(ret == false)
			{
				return true;
			}
			this->freePositionHead.pageIndex = this->getPageNumber()-1;
			this->freePositionHead.chunkIndex = 0;

		}

		return false;
	}
	//  void getAllElements(std::list<Element>&elementList);
	friend class ElementIterator;
	friend class SetElementIterator;
};
